﻿#define _CRT_SECURE_NO_WARNINGS 1
#include<iostream>
#include<vector>
#include<string>
#include<map>
using namespace std;

//namespace hbx1 
//{
//	struct point
//	{
//		int _x;
//		int _y;
//	};
//
//	class Date
//	{
//	public:
//		Date(int year = 1, int month = 1, int day = 1)
//			:_year(year)
//			, _month(month)
//			, _day(day)
//		{}
//
//		Date(const Date& d)
//			:_year(d._year)
//			, _month(d._month)
//			, _day(d._day)
//		{}
//
//	private:
//		int _year;
//		int _month;
//		int _day;
//	};
//
//
//	int main()
//	{
//		//内置类型
//		int x1 = { 2 };
//
//		//自定义类型这里本质是用{ 2025, 1, 1}构造⼀个Date临时对象
//		//临时对象再去拷⻉构造d1，编译器优化后合⼆为⼀变成{ 2025, 1, 1}直接构造初始化
//		Date d1 = { 2024,11,29 };
//		// 这⾥d2引⽤的是{ 2024, 7, 25 }构造的临时对象
//		const Date& d2 = { 2024, 11, 28 };
//		// 需要注意的是C++98⽀持单参数时类型转换，也可以不⽤{}
//		Date d3 = { 2025 };
//		Date d4 = 2025;
//
//		//在c++11中可以省略=
//		point p1{ 1,2 };
//		int x2{ 3 };
//		Date d19{ 2024,11,28 };
//		const Date& d20 { 2024, 11, 28 };
//
//		//在vector容器中插入自定义类型的对象
//		vector<Date> v;
//		v.push_back(d1);
//		v.push_back(Date(2024, 11, 30));
//		v.push_back({ 2024,11,30 });
//		return 0;
//	}
//}

//namespace hbx2
//{
//	int main()
//	{
//		initializer_list<int> mylist;
//		mylist={ 10,20,30 };
//		cout << sizeof(mylist) << endl;
//		return 0;
//	}
//}

//int main()
//{
//	//左值
//	int* p = new int(0);
//	int b = 1;
//	const int c = b;
//	*p = 10;
//	string s("111111");
//	s[0] = 'x';
//	double x = 1.1, y = 2.2;
//
//	//左值引用给左值起别名
//	int*& r1 = p;
//	int& r2 = b;
//	int& r3 = *p;
//	string& r4 = s;
//	char& r5 = s[0];
//	double& r6 = x;
//	double& r7 = y;
//
//	//右值
//	10;
//	x + y;
//	fmin(x, y);
//	string("11111");
//
//	//右值引用给右值起别名
//	int&& rr1 = 10;
//	double&& rr2 = x + y;
//	double&& rr3 = fmin(x, y);
//	string&& rr4 = string("11111");
//
//	//左值引用不能直接引用右值，但是const左值引用可以引用右值。
//	const int&& rx1=10;
//	const double&& rx2=x + y;
//	const double&& rx3=fmin(x, y);
//	const string&& rx4=string("11111");
//
//	//右值引用不能直接引用左值，但是右值引用可以引用move左值。
//	int*&& rrx1 = move (p);
//	int&& rrx2 = move(b);
//	int&& rrx3 = move(*p);
//	string&& rrx4 = move(s);
//	string&& rrx5 = (string&&)s;
//
//}
//

//void f(int& x)
//{
//	cout << "左值引用重载" << endl;
//}
//
//void f(const int& x)
//{
//	cout << "const左值引用重载" << endl;
//}
//
////void f(int&& x)
////{
////	cout << "右值引用重载" << endl;
////}
//
//int main()
//{
//	int a = 1;
//	const int b = 2;
//	f(a);
//	f(b);
//	f(a + b);         //如果没有int&& x,重载就会调用const int&
//	f(move(a));
//
//	//右值引用变量在用于表达式时是左值
//	int&& c = 1;
//	f(c);
//	f(move(c));
//
//	return 0;
//}

//int main()
//{
//	typedef int& l;
//	typedef int&& r;
//	int n = 0;
//	
//	l& r1=n;
//	l&& r2 = n;
//	r& r3 = n;
//	r&& r4 = 1;
//
//	return 0;
//
// }

//template<class T>
//void f1(T& x)
//{}
//
//template<class T>
//void f2(T&& x)
//{}
//
//int main()
//{
//	int n = 0;
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	f1<int>(0); // 报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	f1<int&>(0); // 报错
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	f1<int&&>(0); // 报错
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0);
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//	f1<const int&&>(0);
//	// 没有折叠->实例化为void f2(int&& x)
//	f2<int>(n); // 报错
//	f2<int>(0);
//	// 折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	f2<int&>(0); // 报错
//	// 折叠->实例化为void f2(int&& x)
//	f2<int&&>(n); // 报错
//	f2<int&&>(0);
//
//	return 0;
//}

//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;
//	cout << &a << endl;
//	cout << &x << endl;
//}
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//
//	int a;
//	// a是左值，推导出T为int&，引⽤折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//
//	const int b = 8;
//	// a是左值，推导出T为const int&，引⽤折叠，模板实例化为void Function(const int&t)
//	// 所以Function内部会编译报错，x不能++
//	Function(b); // const 左值
//
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&&t)
//	// 所以Function内部会编译报错，x不能++
//	Function(std::move(b)); // const 右值
//	return 0;
//}

void Fun(int& x) { cout << "左值引用" << endl; }
void Fun(const int& x) { cout << "const 左值引用" << endl; }
void Fun(int&& x) { cout << "右值引用" << endl; }
void Fun(const int&& x) { cout << "const 右值引用" << endl; }

template<class T>
void Function(T&& t)
{
	Fun(t);
}

int main()
{
	const int b = 2;
	int a = 1;
	Fun(a);//传左值
	Fun(0);//传右值
	Fun(b);//const左值引用
	Fun(move(0));//const右值引用
	return 0;
}